import {Environment, OrbitControls} from '@react-three/drei'
import {Map} from './Map.jsx'
import {useEffect, useState} from 'react'
import {insertCoin, isHost, Joystick, myPlayer, onPlayerJoin, useMultiplayerState} from 'playroomkit'
import {CharacterController} from './CharacterController.jsx'
import {Bullet} from './Bullet.jsx'

export const Experience = () => {
  // 玩家
  const [players, setPlayers] = useState([])
  // 子弹
  const [bullets, setBullets] = useState([])
  const [hits, setHits] = useState([])
  const [networkBullets, setNetworkBullets] = useMultiplayerState(
    'bullets',
    []
  )
  const [networkHits, setNetworkHits] = useMultiplayerState('hits', [])

  // 玩家开火方法
  const onFire = (bullet) => {
    // 新增子弹
    setBullets((bullets) => [...bullets, bullet])
    console.log('bullets - length: ', bullets.length)
  }

  const onHit = (bulletId, position) => {
    setBullets((bullets) => bullets.filter((bullet) => bullet.id !== bulletId))
    setHits((hits) => [...hits, {id: bulletId, position}])
  }

  const onKilled = (_victim, killer) => {
    const killerState = players.find((p) => p.state.id === killer).state
    killerState.setState('kills', killerState.state.kills + 1)
  }

  useEffect(() => {
    setNetworkBullets(bullets)
  }, [bullets])


  const start = async () => {
    // Show Playroom lobby UI, Playroom will handle players joining etc and wait for host to tap "Launch"
    await insertCoin()

    // Create a joystick controller for each joining player
    onPlayerJoin((state) => {
      // Joystick will only create UI for current player (myPlayer)
      // For others, it will only sync their state
      const joystick = new Joystick(state, {
        type: 'angular',
        buttons: [
          {id: 'fire', label: 'Fire'}
        ]
      })
      const newPlayer = {state, joystick}
      state.setState('health', 100)
      state.setState('deaths', 0)
      state.setState('kills', 0)
      setPlayers((_players) => [..._players, newPlayer])

      // Probably add a player sprite to the game here.
      state.onQuit(() => {
        // Handle player quitting. Maybe remove player sprite?
        setPlayers(_players => _players.filter(p => p.state.id !== state.id))
      })
    })
  }

  useEffect(() => {
    start()
  }, [])


  return (
    <>
      <directionalLight
        position={[25, 18, -25]}
        intensity={0.3}
        castShadow // Disable shadows on low-end devices
        shadow-camera-near={0}
        shadow-camera-far={100}
        shadow-camera-left={-20}
        shadow-camera-right={20}
        shadow-camera-top={20}
        shadow-camera-bottom={-20}
        shadow-mapSize-width={2048}
        shadow-mapSize-height={2048}
        shadow-bias={-0.0001}
      />
      {/* 取消原始相机 */}
      {/* <OrbitControls/> */}
      <Map/>

      {/* 渲染玩家 */}
      {
        players.map(({state, joystick}, idx) => (
          <CharacterController
            key={state.id + '-' + idx}
            state={state}
            joystick={joystick}
            position-x={idx * 2}
            userPlayer={state.id === myPlayer()?.id}
            onFire={onFire}
            onKilled={onKilled}
          />
        ))
      }

      {/* 渲染子弹集合  isHost() ? bullets : networkBullets */}
      {(isHost() ? bullets : networkBullets).map((bullet, idx) => (
        <Bullet
          key={bullet.id + '-' + idx}
          {...bullet}
          onHit={(position) => onHit(bullet.id, position)}
        />
      ))}

      <Environment files={'/textures/venice_sunset_1k.hdr'}/>
    </>
  )
}
